home *** CD-ROM | disk | FTP | other *** search
- /*
- File: CircularList.java
-
- Originally written by Doug Lea and released into the public domain.
- Thanks for the assistance and support of Sun Microsystems Labs, Agorics
- Inc, Loral, and everyone contributing, testing, and using this code.
-
- History:
- Date Who What
- 24Sep95 dl@cs.oswego.edu Create from collections.java working file
- 13Oct95 dl Changed protection statuses
- */
-
- package collections;
-
- import java.util.Enumeration;
- import java.util.NoSuchElementException;
-
- /**
- *
- * Circular linked lists. Publically Implement only those
- * methods defined in interfaces.
- *
- * @author Doug Lea
- * @version 0.93
- *
- * <P> For an introduction to this package see <A HREF="index.html"> Overview </A>.
- **/
-
-
- public class CircularList extends UpdatableSeqImpl implements UpdatableSeq {
-
- // instance variables
-
- /**
- * The head of the list. Null if empty
- **/
- protected CLCell list_;
-
- // constructors
-
- /**
- * Make an empty list with no element screener
- **/
-
- public CircularList() { this(null, null, 0); }
-
- /**
- * Make an empty list with supplied element screener
- **/
- public CircularList(Predicate screener) { this(screener, null, 0); }
-
- /**
- * Special version of constructor needed by clone()
- **/
-
- protected CircularList(Predicate s, CLCell h, int c) {
- super(s); list_ = h; count_ = c;
- }
-
- /**
- * Make an independent copy of the list. Elements themselves are not cloned
- **/
-
- protected Object clone() throws CloneNotSupportedException {
- if (list_ == null) return new CircularList(screener_, null, 0);
- else return new CircularList(screener_, list_.copyList(), count_);
- }
-
-
- // Collection methods
-
- /**
- * Implements collections.Collection.includes.
- * Time complexity: O(n).
- * @see collections.Collection#includes
- **/
- public synchronized boolean includes(Object element) {
- if (element == null || list_ == null) return false;
- return list_.find(element) != null;
- }
-
- /**
- * Implements collections.Collection.occurrencesOf.
- * Time complexity: O(n).
- * @see collections.Collection#occurrencesOf
- **/
- public synchronized int occurrencesOf(Object element) {
- if (element == null || list_ == null) return 0;
- return list_.count(element);
- }
-
- /**
- * Implements collections.Collection.elements.
- * Time complexity: O(1).
- * @see collections.Collection#elements
- **/
- public synchronized CollectionEnumeration elements() {
- return new CLEnumeration(this, list_);
- }
-
-
- // Seq methods
-
- /**
- * Implements collections.Seq.first.
- * Time complexity: O(1).
- * @see collections.Seq#first
- **/
- public synchronized Object first()
- throws NoSuchElementException {
- return firstCell().element();
- }
-
- /**
- * Implements collections.Seq.last.
- * Time complexity: O(1).
- * @see collections.Seq#last
- **/
- public synchronized Object last()
- throws NoSuchElementException {
- return lastCell().element();
- }
-
- /**
- * Implements collections.Seq.at.
- * Time complexity: O(n).
- * @see collections.Seq#at
- **/
- public synchronized Object at(int index)
- throws NoSuchElementException {
- return cellAt(index).element();
- }
-
- /**
- * Implements collections.Seq.firstIndexOf.
- * Time complexity: O(n).
- * @see collections.Seq#firstIndexOf
- **/
- public synchronized int firstIndexOf(Object element, int startingIndex) {
- if (startingIndex < 0) startingIndex = 0;
- CLCell p = list_;
- if (p == null || element == null) return -1;
- for (int i = 0; true; ++i) {
- if (i >= startingIndex && p.element().equals(element)) return i;
- p = p.next();
- if (p == list_) return -1;
- }
- }
-
-
- /**
- * Implements collections.Seq.lastIndexOf.
- * Time complexity: O(n).
- * @see collections.Seq#lastIndexOf
- **/
- public synchronized int lastIndexOf(Object element, int startingIndex) {
- if (element == null || count_ == 0) return -1;
- if (startingIndex >= size()) startingIndex = size() -1;
- if (startingIndex < 0) startingIndex = 0;
- CLCell p = cellAt(startingIndex);
- int i = startingIndex;
- for (;;) {
- if (p.element().equals(element)) return i;
- else if (p == list_) return -1;
- else {
- p = p.prev();
- --i;
- }
- }
- }
-
- /**
- * Implements collections.Seq.firstIndexOf.
- * Time complexity: O(n).
- * @see collections.Seq#firstIndexOf
- **/
- public synchronized int firstIndexOf(Object element) {
- return firstIndexOf(element, 0);
- }
-
- /**
- * Implements collections.Seq.lastIndexOf.
- * Time complexity: O(n).
- * @see collections.Seq#lastIndexOf
- **/
- public synchronized int lastIndexOf(Object element) {
- return lastIndexOf(element, size()-1);
- }
-
-
- /**
- * Implements collections.Seq.subseq.
- * Time complexity: O(length).
- * @see collections.Seq#subseq
- **/
- public synchronized /* CircularList */ Seq subseq(int from, int length)
- throws NoSuchElementException {
- if (length > 0) {
- checkIndex(from);
- CLCell p = cellAt(from);
- CLCell newlist = new CLCell(p.element());
- CLCell current = newlist;
- for (int i = 1; i < length; ++i) {
- p = p.next();
- if (p == null) checkIndex(from+i); // force exception
- current.addNext(p.element());
- current = current.next();
- }
- return new CircularList(screener_, newlist, length);
- }
- else
- return new CircularList();
- }
-
- // UpdatableCollection methods
-
- /**
- * Implements collections.UpdatableCollection.clear.
- * Time complexity: O(1).
- * @see collections.UpdatableCollection#clear
- **/
- public synchronized void clear() {
- list_ = null;
- setCount(0);
- }
-
- /**
- * Implements collections.UpdatableCollection.exclude.
- * Time complexity: O(n).
- * @see collections.UpdatableCollection#exclude
- **/
- public synchronized void exclude(Object element) {
- remove_(element, true);
- }
-
- /**
- * Implements collections.UpdatableCollection.removeOneOf.
- * Time complexity: O(n).
- * @see collections.UpdatableCollection#removeOneOf
- **/
- public synchronized void removeOneOf(Object element) {
- remove_(element, false);
- }
-
- /**
- * Implements collections.UpdatableCollection.replaceOneOf
- * Time complexity: O(n).
- * @see collections.UpdatableCollection#replaceOneOf
- **/
- public synchronized void replaceOneOf(Object oldElement, Object newElement) throws IllegalElementException {
- replace_(oldElement, newElement, false);
- }
-
- /**
- * Implements collections.UpdatableCollection.replaceAllOf.
- * Time complexity: O(n).
- * @see collections.UpdatableCollection#replaceAllOf
- **/
- public synchronized void replaceAllOf(Object oldElement,
- Object newElement)
- throws IllegalElementException {
- replace_(oldElement, newElement, true);
- }
-
-
- /**
- * Implements collections.UpdatableCollection.take.
- * Time complexity: O(1).
- * takes the last element on the list.
- * @see collections.UpdatableCollection#take
- **/
- public synchronized Object take()
- throws NoSuchElementException {
- Object v = last();
- removeLast();
- return v;
- }
-
-
-
- // UpdatableSeq methods
-
- /**
- * Implements collections.UpdatableSeq.insertFirst.
- * Time complexity: O(1).
- * @see collections.UpdatableSeq#insertFirst
- **/
- public synchronized void insertFirst(Object element)
- throws IllegalElementException {
- checkElement(element);
- if (list_ == null) list_ = new CLCell(element);
- else list_ = list_.addPrev(element);
- incCount();
- }
-
- /**
- * Implements collections.UpdatableSeq.replaceFirst.
- * Time complexity: O(1).
- * @see collections.UpdatableSeq#replaceFirst
- **/
- public synchronized void replaceFirst(Object element)
- throws IllegalElementException {
- checkElement(element);
- firstCell().element(element);
- incVersion();
- }
-
- /**
- * Implements collections.UpdatableSeq.removeFirst.
- * Time complexity: O(1).
- * @see collections.UpdatableSeq#removeFirst
- **/
- public synchronized void removeFirst()
- throws NoSuchElementException {
- if (firstCell().isSingleton())
- list_ = null;
- else {
- CLCell n = list_.next();
- list_.unlink();
- list_ = n;
- }
- decCount();
- }
-
- /**
- * Implements collections.UpdatableSeq.insertLast.
- * Time complexity: O(1).
- * @see collections.UpdatableSeq#insertLast
- **/
- public synchronized void insertLast(Object element)
- throws IllegalElementException {
- if (list_ == null) insertFirst(element);
- else {
- checkElement(element);
- list_.prev().addNext(element);
- incCount();
- }
- }
-
- /**
- * Implements collections.UpdatableSeq.replaceLast.
- * Time complexity: O(1).
- * @see collections.UpdatableSeq#replaceLast
- **/
- public synchronized void replaceLast(Object element)
- throws IllegalElementException, NoSuchElementException {
- checkElement(element);
- lastCell().element(element);
- incVersion();
- }
-
-
- /**
- * Implements collections.UpdatableSeq.removeLast.
- * Time complexity: O(1).
- * @see collections.UpdatableSeq#removeLast
- **/
- public synchronized void removeLast()
- throws NoSuchElementException {
- CLCell l = lastCell();
- if (l == list_) list_ = null;
- else l.unlink();
- decCount();
- }
-
- /**
- * Implements collections.UpdatableSeq.insertAt.
- * Time complexity: O(n).
- * @see collections.UpdatableSeq#insertAt
- **/
- public synchronized void insertAt(int index, Object element)
- throws IllegalElementException, NoSuchElementException {
- if (index == 0) insertFirst(element);
- else {
- checkElement(element);
- cellAt(index - 1).addNext(element);
- incCount();
- }
- }
-
- /**
- * Implements collections.UpdatableSeq.replaceAt.
- * Time complexity: O(n).
- * @see collections.UpdatableSeq#replaceAt
- **/
- public synchronized void replaceAt(int index, Object element)
- throws IllegalElementException, NoSuchElementException {
- checkElement(element);
- cellAt(index).element(element);
- incVersion();
- }
-
- /**
- * Implements collections.UpdatableSeq.removeAt.
- * Time complexity: O(n).
- * @see collections.UpdatableSeq#removeAt
- **/
- public synchronized void removeAt(int index)
- throws NoSuchElementException {
- if (index == 0) removeFirst();
- else {
- cellAt(index - 1).unlinkNext();
- decCount();
- }
- }
-
- /**
- * Implements collections.UpdatableSeq.prependElements.
- * Time complexity: O(number of elements in e).
- * @see collections.UpdatableSeq#prependElements
- **/
- public synchronized void prependElements(Enumeration e)
- throws IllegalElementException, CorruptedEnumerationException {
- CLCell hd = null;
- CLCell current = null;
- while (e.hasMoreElements()) {
- Object element = e.nextElement();
- checkElement(element);
- incCount();
- if (hd == null) {
- hd = new CLCell(element);
- current = hd;
- }
- else {
- current.addNext(element);
- current = current.next();
- }
- }
- if (list_ == null)
- list_ = hd;
- else if (hd != null) {
- CLCell tl = list_.prev();
- current.next(list_); list_.prev(current);
- tl.next(hd); hd.prev(tl);
- list_ = hd;
- }
- }
-
- /**
- * Implements collections.UpdatableSeq.appendElements.
- * Time complexity: O(number of elements in e).
- * @see collections.UpdatableSeq#appendElements
- **/
- public synchronized void appendElements(Enumeration e)
- throws IllegalElementException, CorruptedEnumerationException {
- if (list_ == null) prependElements(e);
- else {
- CLCell current = list_.prev();
- while (e.hasMoreElements()) {
- Object element = e.nextElement();
- checkElement(element);
- incCount();
- current.addNext(element);
- current = current.next();
- }
- }
- }
-
- /**
- * Implements collections.UpdatableSeq.insertElementsAt.
- * Time complexity: O(size() + number of elements in e).
- * @see collections.UpdatableSeq#insertElementsAt
- **/
- public synchronized void insertElementsAt(int index, Enumeration e)
- throws IllegalElementException, CorruptedEnumerationException,
- NoSuchElementException {
- if (list_ == null || index == 0) prependElements(e);
- else {
- CLCell current = cellAt(index - 1);
- while (e.hasMoreElements()) {
- Object element = e.nextElement();
- checkElement(element);
- incCount();
- current.addNext(element);
- current = current.next();
- }
- }
- }
-
-
- /**
- * Implements collections.UpdatableSeq.removeFromTo.
- * Time complexity: O(n).
- * @see collections.UpdatableSeq#removeFromTo
- **/
- public synchronized void removeFromTo(int fromIndex, int toIndex)
- throws NoSuchElementException {
- checkIndex(toIndex);
- CLCell p = cellAt(fromIndex);
- CLCell last = list_.prev();
- for (int i = fromIndex; i <= toIndex; ++i) {
- decCount();
- CLCell n = p.next();
- p.unlink();
- if (p == list_) {
- if (p == last) {
- list_ = null;
- return;
- }
- else
- list_ = n;
- }
- p = n;
- }
- }
-
-
- // helper methods
-
- /**
- * return the first cell, or throw exception if empty
- **/
- private CLCell firstCell() throws NoSuchElementException {
- if (list_ != null) return list_;
- checkIndex(0);
- return null; // not reached!
-
- }
-
- /**
- * return the last cell, or throw exception if empty
- **/
- private CLCell lastCell() throws NoSuchElementException {
- if (list_ != null) return list_.prev();
- checkIndex(0);
- return null; // not reached!
- }
-
- /**
- * return the index'th cell, or throw exception if bad index
- **/
- private CLCell cellAt(int index) throws NoSuchElementException {
- checkIndex(index);
- return list_.nth(index);
- }
-
- /**
- * helper for remove/exclude
- **/
- private void remove_(Object element, boolean allOccurrences)
- throws IllegalElementException {
- if (element == null || list_ == null) return;
- CLCell p = list_;
- for (;;) {
- CLCell n = p.next();
- if (p.element().equals(element)) {
- decCount();
- p.unlink();
- if (p == list_) {
- if (p == n) {
- list_ = null;
- break;
- }
- else list_ = n;
- }
- if (!allOccurrences) break;
- else p = n;
- }
- else if (n == list_)
- break;
- else
- p = n;
- }
- }
-
-
- /**
- * helper for replace*
- **/
- private void replace_(Object oldElement, Object newElement,
- boolean allOccurrences)
- throws IllegalElementException {
- if (oldElement == null || list_ == null) return;
- CLCell p = list_;
- do {
- if (p.element().equals(oldElement)) {
- checkElement(newElement);
- incVersion();
- p.element(newElement);
- if (!allOccurrences) return;
- }
- p = p.next();
- } while (p != list_);
- }
-
- // ImplementationCheckable methods
-
- /**
- * Implements collections.ImplementationCheckable.checkImplementation.
- * @see collections.ImplementationCheckable#checkImplementation
- **/
-
- public synchronized void checkImplementation()
- throws ImplementationError {
-
- super.checkImplementation();
-
- assert(((count_ == 0) == (list_ == null)));
- assert((list_ == null || list_.length() == count_));
-
- if (list_ == null) return;
-
- int c = 0;
- CLCell p = list_;
- do {
- assert(p.prev().next() == p);
- assert(p.next().prev() == p);
- assert(canInclude(p.element()));
- assert(occurrencesOf(p.element()) > 0);
- assert(includes(p.element()));
- p = p.next();
- ++c;
- }
- while (p != list_);
-
- assert(c == count_);
-
- }
- }
-
-